Multi Threading

C++11 부터 동시성 기능이 도입되었다.

C++ 동시성 프로그래밍 기본 구성 요소
- thread:    새로운 실행 경로를 위한 클래스
- async:    함수를 비동기로 호출
- atomic:    인터리브(Interleave)되지 않은 값에 접근하기 위한 템플릿 클래스
- mutex:    상호 배타적인 실행을 조정하는 클래스
- future:    thread로부터 결과를 받기 위한 클래스 템플릿
- promise: future를 위한 값을 저장하는 템플릿
비동기식(Asyncchrony)
해결 프로그램을 실행하는 동안 이미 다음 모델에서 작업할 수 있음

인터럽트 가능성(Interruptibility)
새로운 모델이 좋다고 확신하면 이전 모델의 해결 프로그램을 중단
class interruptible_iteration{
public:
interruptible_iteration(basic_iteration<double>& iter)
: iter(iter), interrupted(false) {}
bool finished(double r){
return iter.finished(r) || iterrupted.load();
}
void interrupt(){ interrupted=true; }
bool is_interrupted() const { return interrupted.load(); }
private:
basic_iteration<double>& iter;
std::atomic<bool> interrupted;
};
template <typename Solver>
class async_executor{
public:
async_executor(const Solver& solver): my_solver(solver), my_iter{}, my_thread{} {}
template <typename VectorB, typename VectorX, typename Iteration>
void start_solve(const VectorB& b, VectorX& x, Iteration& iter) const{
my_iter.set_iter(iter);
my_thread=std::thread(
[this, &b, &x](){
return my_solver.solve(b, x, my_iter);
}
);
}
int wait(void){
my_thread.join();
return my_iter.error_code();
}
int interrupt(void){
my_iter.interrupt();
return wait();
}
bool finished() const{ return my_iter.iter->finished(); }
private:
Solver my_solver;
mutable interruptible_iteration my_iter;
mutable std::thread my_thread;
};
interruptible_iteration 클래스는 인터럽트 여부를 나타내는 bool을 포함한다.
(atomic<bool>은 다른 스레드에 의한 접근을 방해하지 않음)

interrupt 메서드는 반복이 끝날 때, 해결 프로그램을 종료한다.
-> 해결 프로그램을 시작하면 해결 프로그램이 종료된 후에만 다음 명령을 실행할 수 있다.

async_executor 클래스를 이용해서 해결 프로그램이 시작된 이후,
다른 작업을 하면서 해결 프로그래밍 종료되었는지 수시로 확인할 수 있다.
결과가 부적합해졌다는 것을 알게되면, 실행을 중단할 수 있다.
while(!happy(science_foundation)){
discretize_model();
auto my_solver=itl::make_cg_solver(A, PC);
itl::async_executor<decltype(my_solver)> async_exec(my_solver);
async_exec.start_solver(x, b, iter);
play_with_model();
if(found_better_model) async_exec.interrupt();
else async_exec.wait();
}